home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / dflat_r_.arc / POPDOWN.C < prev    next >
Text File  |  1991-10-02  |  8KB  |  313 lines

  1. /* ------------- popdown.c ----------- */
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <ctype.h>
  7. #include <dos.h>
  8. #include "dflat.h"
  9.  
  10. static int SelectionWidth(struct PopDown *);
  11.  
  12. int PopDownProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
  13. {
  14.     static int py = -1;
  15.     int my = (int) p2 - GetTop(wnd);
  16.     int wd, rtn, i;
  17.     struct PopDown *pd1;
  18.     unsigned char sep[80], *cp = sep;
  19.     unsigned char sel[80];
  20.     struct PopDown *ActivePopDown = NULL;
  21.     WINDOW currFocus;
  22.  
  23.     switch (msg)    {
  24.         case CREATE_WINDOW:
  25.             ClearAttribute(wnd, HASTITLEBAR     |
  26.                                 VSCROLLBAR     |
  27.                                 MOVEABLE     |
  28.                                 SIZEABLE     |
  29.                                 HSCROLLBAR);
  30.             rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
  31.             SendMessage(wnd, CAPTURE_MOUSE, 0, 0);
  32.             SendMessage(wnd, CAPTURE_KEYBOARD, 0, 0);
  33.             SendMessage(NULLWND, SAVE_CURSOR, 0, 0);
  34.             SendMessage(NULLWND, HIDE_CURSOR, 0, 0);
  35.             return rtn;
  36.         case LEFT_BUTTON:
  37.             if (InsideRect(p1, p2, ClientRect(wnd)))    {
  38.                 if (my != py)    {
  39.                     SendMessage(wnd, LB_SELECTION,
  40.                             (PARAM) wnd->wtop+my-1, TRUE);
  41.                     py = my;
  42.                 }
  43.             }
  44.             else if ((int)p2 == GetTop(GetParent(wnd)))
  45.                 if (GetClass(GetParent(wnd)) == MENUBAR)
  46.                     PostMessage(GetParent(wnd), msg, p1, p2);
  47.             return FALSE;
  48.         case DOUBLE_CLICK:
  49.             return TRUE;
  50.         case LB_SELECTION:
  51.             if (*TextLine(wnd, (int)p1) == LINE)
  52.                 return TRUE;
  53.             wnd->mnu->Selection = (int)p1;
  54.             break;
  55.         case BUTTON_RELEASED:
  56.             py = -1;
  57.             if (InsideRect((int)p1, (int)p2, ClientRect(wnd)))    {
  58.                 int sel = (int)p2 - GetClientTop(wnd);
  59.                 if (*TextLine(wnd, sel) != LINE)
  60.                     SendMessage(wnd, LB_CHOOSE, wnd->selection, 0);
  61.             }
  62.             else    {
  63.                 WINDOW pwnd = GetParent(wnd);
  64.                 if (GetClass(pwnd) == MENUBAR && (int)p2 == GetTop(pwnd))
  65.                     break;
  66.                 if ((int)p1 == GetLeft(pwnd)+2)
  67.                     break;
  68.                 SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  69.                 return TRUE;
  70.             }
  71.             break;
  72.         case BUILD_SELECTIONS:
  73.             wnd->mnu = (void *) p1;
  74.             wnd->selection = wnd->mnu->Selection;
  75.             break;
  76.         case PAINT:
  77.             if (wnd->mnu == NULL)
  78.                 return TRUE;
  79.             ActivePopDown = pd1 = wnd->mnu->Selections;
  80.             wd = MenuWidth(ActivePopDown)-2;
  81.             while (wd--)
  82.                 *cp++ = LINE;
  83.             *cp = '\0';
  84.             SendMessage(wnd, CLEARTEXT, 0, 0);
  85.             wnd->selection = wnd->mnu->Selection;
  86.             while (pd1->SelectionTitle != NULL)    {
  87.                 if (*pd1->SelectionTitle == LINE)
  88.                     SendMessage(wnd, ADDTEXT, (PARAM) sep, 0);
  89.                 else    {
  90.                     int len;
  91.                     memset(sel, '\0', sizeof sel);
  92.                     if (pd1->Attrib & INACTIVE)
  93.                         sprintf(sel, "%c%c%c",
  94.                             CHANGECOLOR,
  95.                             wnd->WindowColors [HILITE_COLOR] [FG] | 0x80,
  96.                             wnd->WindowColors [STD_COLOR] [BG] | 0x80);
  97.                     strcat(sel, " ");
  98.                     if (pd1->Attrib & CHECKED)
  99.                         sel[strlen(sel)-1] = CHECKMARK;
  100.                     len = CopyCommand(sel+strlen(sel), pd1->SelectionTitle,
  101.                             pd1->Attrib & INACTIVE, wnd->WindowColors [STD_COLOR] [BG]);
  102.                     if (pd1->Accelerator)    {
  103.                         int i;
  104.                         int wd1 = 2+SelectionWidth(ActivePopDown) - strlen(pd1->SelectionTitle);
  105.                         for (i = 0; keys[i].keylabel; i++)    {
  106.                             if (keys[i].keycode == pd1->Accelerator)    {
  107.                                 while (wd1--)
  108.                                     strcat(sel, " ");
  109.                                 sprintf(sel+strlen(sel), "[%s]", keys[i].keylabel);
  110.                                 break;
  111.                             }
  112.                         }
  113.                     }
  114.                     if (pd1->Attrib & CASCADED)    {
  115.                         if (!pd1->Accelerator)    {
  116.                             wd = MenuWidth(ActivePopDown)-len+1;
  117.                             while (wd--)
  118.                                 strcat(sel, " ");
  119.                         }
  120.                         sel[strlen(sel)-1] = CASCADEPOINTER;
  121.                     }
  122.                     else
  123.                         strcat(sel, " ");
  124.                     strcat(sel, " ");
  125.                     sel[strlen(sel)-1] = RESETCOLOR;
  126.                     SendMessage(wnd, ADDTEXT, (PARAM) sel, 0);
  127.                 }
  128.                 pd1++;
  129.             }
  130.             break;
  131.         case BORDER:
  132.             if (wnd->mnu == NULL)
  133.                 return TRUE;
  134.             currFocus = inFocus;
  135.             inFocus = NULLWND;
  136.             rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, FALSE);
  137.             inFocus = currFocus;
  138.  
  139.             for (i = 0; i < ClientHeight(wnd); i++)    {
  140.                 if (*TextLine(wnd, i) == LINE)    {
  141.                     wputch(wnd, LEDGE, 0, i+1);
  142.                     wputch(wnd, REDGE, WindowWidth(wnd)-1, i+1);
  143.                 }
  144.             }
  145.             return rtn;
  146.  
  147.         case LB_CHOOSE:
  148.             ActivePopDown = wnd->mnu->Selections;
  149.             if (ActivePopDown != NULL)    {
  150.                 int *attr = &(ActivePopDown+(int)p1)->Attrib;
  151.                 wnd->mnu->Selection = (int)p1;
  152.                 if (*attr & INACTIVE)
  153.                     beep();
  154.                 else if (*attr & TOGGLE)    {
  155.                     unsigned char *tl = TextLine(wnd, (int)p1);
  156.                     *attr ^= CHECKED;
  157.                     if (*attr & CHECKED)
  158.                         *tl = CHECKMARK;
  159.                     else
  160.                         *tl = ' ';
  161.                     SendMessage(wnd, PAINT, 0, 0);
  162.                 }
  163.                 else
  164.                     PostMessage(GetParent(wnd), COMMAND,
  165.                         (ActivePopDown+(int)p1)->ActionId, p1);
  166.             }
  167.             return TRUE;
  168.         case KEYBOARD:
  169.             if (wnd->mnu != NULL)    {
  170.                 ActivePopDown = wnd->mnu->Selections;
  171.                 if (ActivePopDown != NULL)    {
  172.                     int c = (int)p1;
  173.                     int sel = 0;
  174.                     int a;
  175.                     struct PopDown *pd = ActivePopDown;
  176.  
  177.                     if ((c & OFFSET) == 0)
  178.                         c = tolower(c);
  179.                     a = AltConvert(c);
  180.  
  181.                     while (pd->SelectionTitle != NULL)    {
  182.                         char *cp = strchr(pd->SelectionTitle,
  183.                                         SHORTCUTCHAR);
  184.                         int sc = tolower(*(cp+1));
  185.                         if ((cp && sc == c) ||
  186.                                 (a && sc == a) ||
  187.                                     pd->Accelerator == c)    {
  188.                             PostMessage(wnd, LB_SELECTION, sel, 0);
  189.                             PostMessage(wnd, LB_CHOOSE, sel, TRUE);
  190.                             return TRUE;
  191.                         }
  192.                         pd++, sel++;
  193.                     }
  194.                 }
  195.             }
  196.             switch ((int)p1)    {
  197.                 case F1:
  198. #ifdef INCLUDE_HELP
  199.                     if (ActivePopDown == NULL)
  200.                         SendMessage(GetParent(wnd), msg, p1, p2);
  201.                     else 
  202.                         DisplayHelp(wnd, (ActivePopDown+wnd->selection)->help);
  203.                     return TRUE;
  204. #endif
  205.                 case ESC:
  206.                     SendMessage(wnd, CLOSE_WINDOW, TRUE, 0);
  207.                     return TRUE;
  208.                 case FWD:
  209.                 case BS:
  210.                     if (GetClass(GetParent(wnd)) == MENUBAR)
  211.                         PostMessage(GetParent(wnd), KEYBOARD, p1, p2);
  212.                     return TRUE;
  213.                 case UP:
  214.                     if (wnd->selection == 0)    {
  215.                         if (wnd->wlines == ClientHeight(wnd))    {
  216.                             PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
  217.                             return TRUE;
  218.                         }
  219.                     }
  220.                     break;
  221.                 case DN:
  222.                     if (wnd->selection == wnd->wlines-1)    {
  223.                         if (wnd->wlines == ClientHeight(wnd))    {
  224.                             PostMessage(wnd, LB_SELECTION, 0, FALSE);
  225.                             return TRUE;
  226.                         }
  227.                     }
  228.                     break;
  229.                 case HOME:
  230.                 case END:
  231.                 case '\r':
  232.                     break;
  233.                 default:
  234.                     return FALSE;
  235.             }
  236.             break;
  237.         case CLOSE_WINDOW:    {
  238.             WINDOW pwnd = GetParent(wnd);
  239.             SendMessage(wnd, RELEASE_MOUSE, 0, 0);
  240.             SendMessage(wnd, RELEASE_KEYBOARD, 0, 0);
  241.             SendMessage(NULLWND, RESTORE_CURSOR, 0, 0);
  242.             rtn = BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
  243.             SendMessage(pwnd, CLOSE_POPDOWN, p1, 0);
  244.             return rtn;
  245.         }
  246.         default:
  247.             break;
  248.     }
  249.     return BaseWndProc(POPDOWNMENU, wnd, msg, p1, p2);
  250. }
  251.  
  252. int MenuHeight(struct PopDown *pd)
  253. {
  254.     int ht = 0;
  255.     while (pd[ht].SelectionTitle != NULL)
  256.         ht++;
  257.     return ht+2;
  258. }
  259.  
  260. int MenuWidth(struct PopDown *pd)
  261. {
  262.     int wd = 0, i;
  263.     int len = 0;
  264.  
  265.     wd = SelectionWidth(pd);
  266.     while (pd->SelectionTitle != NULL)    {
  267.         if (pd->Accelerator)    {
  268.             for (i = 0; keys[i].keylabel; i++)
  269.                 if (keys[i].keycode == pd->Accelerator)    {
  270.                     len = max(len, 2+strlen(keys[i].keylabel));
  271.                     break;
  272.                 }
  273.         }
  274.         if (pd->Attrib & CASCADED)
  275.             len = max(len, 2);
  276.         pd++;
  277.     }
  278.     return wd+5+len;
  279. }
  280.  
  281. static int SelectionWidth(struct PopDown *pd)
  282. {
  283.     int wd = 0;
  284.     while (pd->SelectionTitle != NULL)    {
  285.         int len = strlen(pd->SelectionTitle)-1;
  286.         wd = max(wd, len);
  287.         pd++;
  288.     }
  289.     return wd;
  290. }
  291.  
  292. int CopyCommand(unsigned char *dest, unsigned char *src,
  293.                                         int skipcolor, int bg)
  294. {
  295.     unsigned char *d = dest;
  296.     while (*src && *src != '\n')    {
  297.         if (*src == SHORTCUTCHAR)    {
  298.             src++;
  299.             if (!skipcolor)    {
  300.                 *dest++ = CHANGECOLOR;
  301.                 *dest++ = cfg.clr[POPDOWNMENU] [HILITE_COLOR] [BG] | 0x80;
  302.                 *dest++ = bg | 0x80;
  303.                 *dest++ = *src++;
  304.                 *dest++ = RESETCOLOR;
  305.             }
  306.         }
  307.         else
  308.             *dest++ = *src++;
  309.     }
  310.     return (int) (dest - d);
  311. }
  312.  
  313.